import React, { Component, Children, PureComponent } from "react";
import "./index.less";

export default class DropdownMenu extends PureComponent {
  menuBar = null;

  popup = null;

  popupContent = null;

  constructor(props) {
    super(props);
    this.state = {
      showItems: false,
      active: 0,
    };
    this.toggle = this.toggle.bind(this);
    this.handleWindowScroll = this.handleWindowScroll.bind(this);
  }

  /**
   * 控制子菜单的展示
   */
  toggle(index) {
    let { popupContent, popup } = this;
    let { showItems, active } = this.state;
    if (index !== undefined && active !== index && showItems === true) {
      stopMove();

      popupContent.classList.remove("slide-top--show");
      popupContent.classList.add("slide-reset");
      popup.style.display = "block";

      requestAnimationFrame(() => {
        popupContent.classList.remove("slide-reset");
        this.setState({ showItems: true, active: index });
        popupContent.classList.add("slide-top--show");
      });
      return;
    }
    if (showItems === false) {
      popup.style.display = "block";
      stopMove();
    } else {
      canMove();
    }

    requestAnimationFrame(() => {
      this.setState({
        showItems: !this.state.showItems,
        active: index !== undefined ? index : active,
      });

      this.state.showItems
        ? popupContent.classList.add("slide-top--show")
        : popupContent.classList.remove("slide-top--show");
    });
  }

  componentDidMount() {
    this.handleWindowScroll();

    window.addEventListener("scroll", this.handleWindowScroll);
  }

  componentWillUnmount() {
    window.removeEventListener("scroll", this.handleWindowScroll);
  }

  handleWindowScroll(e) {
    let { menuBar, popup } = this;

    if (menuBar) {
      popup.style.top =
        menuBar.offsetTop - window.scrollY + menuBar.clientHeight + "px";
    }
  }

  render() {
    const { showItems, active } = this.state;
    const { children } = this.props;

    const buttons = Children.map(children, (child, index) => {
      return (
        <div
          className={`b-dropdown-menu__btn ${
            showItems && active === index ? "b-dropdown-menu__btn--active" : ""
          }`}
          onClick={() => {
            this.toggle(index);
          }}
        >
          {child}
        </div>
      );
    });
    return (
      <div className="b-dropdown-menu">
        <div
          className="b-dropdown-menu__bar"
          ref={(v) => {
            this.menuBar = v;
          }}
        >
          {buttons}
        </div>
        <div
          className="b-dropdown-popup"
          ref={(v) => {
            this.popup = v;
          }}
          onClick={() => {
            this.toggle();
          }}
          style={{ display: "none" }}
        >
          <div
            className={`b-dropdown-popup-content slide-top`}
            ref={(v) => {
              this.popupContent = v;
            }}
            onTransitionEnd={() => {
              if (this.state.showItems === false)
                this.popup.style.display = "none";
            }}
          >
            {children[active].props.renderContent
              ? children[active].props.renderContent()
              : null}
          </div>
        </div>
      </div>
    );
  }
}

function stopMove() {
  document.body.style.overflow = "hidden";
  document.body.addEventListener("touchmove", bodyScroll, {
    passive: false,
  });
}

function canMove() {
  document.body.style.overflow = "";
  document.body.removeEventListener("touchmove", bodyScroll, {
    passive: false,
  });
}

function bodyScroll(event) {
  event.preventDefault();
}
